package com.attilax.io;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;

import com.attilax.collection.mapBuilder;
import com.attilax.core.ForeachFunction;
import com.attilax.core.ForeachFunctionV2;
import com.attilax.util.ExUtil;
import com.attilax.util.timestampUtil;
import com.cnhis.cloudhealth.module.log.Cls1;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

public class DirTraveService {
	public static Logger logger = Logger.getLogger(Cls1.class);

	public static void main(String[] args) {
		DirTraveService dts = new DirTraveService();
		final String dir = "C:\\Users\\attilax\\Documents\\s2018 s4 doc compc dtS44";
		dts.traveV4Vs427(dir, new Function<File, Object>() {

			@Override
			public Object apply(File arg0) {
				logger.info("arg0:" + arg0.getAbsolutePath());
				String reltpath = PathService.relpath(arg0.getAbsolutePath(), dir);
				String newFileTxtmode4index = "c:\\00txtmodeIndexdir\\" + reltpath + ".txt";
				try {
					String txtcontext = "data" + timestampUtil.gettimeStamp_millsec();
					logger.info("txtcontext:" + txtcontext);
					FileUtils.write(new File(newFileTxtmode4index), txtcontext);
				} catch (IOException e) {

					e.printStackTrace();
					logger.error(e);
				}
				return null;
			}
		}, new Function<Integer, Object>() {

			@Override
			public Object apply(Integer cnt_index) {
				// Map m=Maps.newConcurrentMap();m.put("index", cnt_index)
				logger.info("cnt_index:" + cnt_index);
				return null;
			}
		});
	}

	int count = 0;

	public List<Map> traveExs = Lists.newArrayList();

	/**
	 * ingo ex ,and log ,and save ex in to li.. *
	 * 
	 * 
	 * @param strPath
	 * @param fun
	 */
	public static void traveV6_vS531(File dir, ForeachFunctionV2 fun) {
		new DirTraveService().traveV6_vS531_core(dir, fun);
	}

	public void trave_allSubFile_IncDir(File rootDir, ForeachFunctionV2 fun) {

		File[] files = rootDir.listFiles();

		if (files == null)
			return;
		int length = files.length;
		for (int i = 0; i < length; i++) {
			File f = files[i];
			if (f.isDirectory()) {
			
				trave_allSubFile_IncDir(f, fun);
				trave_process(fun, f);
			} else {

				trave_process(fun, f);

			}
		}
	}
@Deprecated
	private void trave_allFile_IncDir_NselfDir(File dubdir, ForeachFunctionV2 fun) {
		File[] files = dubdir.listFiles();

		if (files == null)
			return;
		int length = files.length;
		for (int i = 0; i < length; i++) {
			File f = files[i];
			if (f.isDirectory()) {
				trave_process(fun, f);
				trave_allFile_IncDir_NselfDir(f, fun);
			} else {

				trave_process(fun, f);

			}
		}
		
	}

	private void trave_process(ForeachFunctionV2 fun, File f) {
		try {
			count++;
			fun.each(count, f, 0);
		} catch (BreakException e) {
			Map dbginfo = mapBuilder.$().put("index", count).put("file", f).build();
			ExUtil.throwExV4("fun.each ex", e, dbginfo);
		} catch (Exception e) {
			@SuppressWarnings("rawtypes")
			Map m = Maps.newConcurrentMap();
			m.put("file", f);
			m.put("ex", e);
			traveExs.add(m);
		}
	}

	public void traveV6_vS531_core(File dir, ForeachFunctionV2 fun) {
		// File dir = new File(strPath);

		// Function<T, R>
		File[] files = dir.listFiles();

		if (files == null)
			return;
		int length = files.length;
		for (int i = 0; i < length; i++) {

			if (files[i].isDirectory()) {
				traveV6_vS531_core(files[i], fun);
			} else {

				File f = files[i];
				trave_process(fun, f);

				// logger.info("--now process count:"+String.valueOf(count));
			}
		}
	}

	/**
	 * ingo ex ,and log ,and save ex in to li.. *
	 * 
	 * 
	 * @param strPath
	 * @param fun
	 */
	public void traveV5_vS522(File dir, ForeachFunction fun) {
		// File dir = new File(strPath);

		// Function<T, R>
		File[] files = dir.listFiles();

		if (files == null)
			return;
		int length = files.length;
		for (int i = 0; i < length; i++) {

			if (files[i].isDirectory()) {
				traveV5_vS522(files[i], fun);
			} else {

				File f = files[i];
				try {
					count++;
					fun.each(count, f);
				} catch (BreakException e) {
					Map dbginfo = mapBuilder.$().put("index", count).put("file", f).build();
					ExUtil.throwExV4("fun.each ex", e, dbginfo);
				} catch (Exception e) {
					Map m = Maps.newConcurrentMap();
					m.put("file", f);
					m.put("ex", e);
					traveExs.add(m);
				}

				// logger.info("--now process count:"+String.valueOf(count));
			}
		}
	}

	/**
	 * ingo ex ,and log ,and save ex in to li.. *
	 * 
	 * 
	 * @param strPath
	 * @param fun
	 */
	public void traveV4Vs427(String strPath, Function fun, Function fun_log) {
		File dir = new File(strPath);

		// Function<T, R>
		File[] files = dir.listFiles();

		if (files == null)
			return;
		int length = files.length;
		for (int i = 0; i < length; i++) {
			if (files[i].isDirectory()) {
				traveV4Vs427(files[i].getAbsolutePath(), fun, fun_log);
			} else {
				File strFileName = files[i];
				try {
					fun.apply(strFileName);
				} catch (Exception e) {
					Map m = Maps.newConcurrentMap();
					m.put("file", strFileName);
					m.put("ex", e);
				}
				count++;
				fun_log.apply(count);
				// logger.info("--now process count:"+String.valueOf(count));
			}
		}
	}

	/**
	 * ingo ex ,and log ,and save ex in to li.. *
	 * 
	 * 
	 * @param strPath
	 * @param fun
	 */
	public void trave_throwEx(String strPath, Function fun, Function fun_log) {
		File dir = new File(strPath);

		// Function<T, R>
		File[] files = dir.listFiles();

		if (files == null)
			return;
		int length = files.length;
		for (int i = 0; i < length; i++) {
			if (files[i].isDirectory()) {
				trave_throwEx(files[i].getAbsolutePath(), fun, fun_log);
			} else {
				File strFileName = files[i];

				fun.apply(strFileName);

				count++;
				fun_log.apply(count);
				// logger.info("--now process count:"+String.valueOf(count));
			}
		}
	}

	public static Function nullFunc() {
		Function fc = new Function<Integer, Object>() {

			@Override
			public Object apply(Integer cnt_index) {
				// Map m=Maps.newConcurrentMap();m.put("index", cnt_index)
				// logger.info("cnt_index:"+cnt_index);
				return null;
			}
		};
		return fc;
	}

}
